package work.xiaohong.websocket.client;


import com.alibaba.fastjson.JSON;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.timeout.IdleStateEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.yeauty.annotation.*;
import org.yeauty.pojo.Session;
import work.xiaohong.common.constant.MessageStatus;
import work.xiaohong.common.constant.MessageType;
import work.xiaohong.websocket.vo.SendMsgVo;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author xiaohong
 * @version 1.0
 * @date 2021/9/25 0025 12:11
 * @description 创建WebSocket服务
 */
@Component
@ServerEndpoint(host = "${ws.host}",port = "${ws.port}",path = "/chat/{arg}")
public class MyWebSocketClient {

    //将所有客户端对象储存到Map集合中
    public static Map<String, Session> chatClients = new ConcurrentHashMap<>();

    /**
     * 当有新的连接进入时，对该方法进行回调
     * @param session
     * @param headers
     * @param req
     * @param reqMap
     * @param arg
     * @param pathMap
     */
    @BeforeHandshake
    public void handshake(Session session, HttpHeaders headers, @RequestParam String req, @RequestParam MultiValueMap reqMap, @PathVariable String arg, @PathVariable Map pathMap){
        session.setSubprotocols("stomp");
        session.setAttribute("key",arg);
//        if (!"ok".equals(req)){
//            System.out.println("Authentication failed!");
//            session.close();
//        }
    }

    /**
     * 当有新的WebSocket连接完成时，对该方法进行回调
     * @param session
     * @param headers
     * @param req
     * @param reqMap
     * @param arg
     * @param pathMap
     */
    @OnOpen
    public void onOpen(Session session, HttpHeaders headers, @RequestParam String req, @RequestParam MultiValueMap reqMap, @PathVariable String arg, @PathVariable Map pathMap){
        System.out.println("new connection");
        System.out.println(req);
        // 保存连接信息
        chatClients.put(arg,session);
        System.out.println("当前连接数："+chatClients.size());
    }

    /**
     * 当有WebSocket连接关闭时，对该方法进行回调
     * @param session
     * @throws IOException
     */
    @OnClose
    public void onClose(Session session) throws IOException {
        System.out.println("one connection closed");
        chatClients.remove(session.getAttribute("key"));
        System.out.println("当前连接数："+chatClients.size());
    }

    /**
     * 当有WebSocket抛出异常时，对该方法进行回调
     * @param session
     * @param throwable
     */
    @OnError
    public void onError(Session session, Throwable throwable) {
        throwable.printStackTrace();
    }

    /**
     * 当接收到字符串消息时，对该方法进行回调
     * @param session
     * @param message
     */
    @OnMessage
    public void onMessage(Session session, String message) {
        System.out.println(message);
        SendMsgVo sendMsgVo = JSON.parseObject(message, SendMsgVo.class);
        sendMsgVo.setType(MessageType.HEARTRESPONSE.getType());
        session.sendText(JSON.toJSONString(sendMsgVo));
    }

    /**
     * 当接收到二进制消息时，对该方法进行回调
     * @param session
     * @param bytes
     */
    @OnBinary
    public void onBinary(Session session, byte[] bytes) {
        for (byte b : bytes) {
            System.out.println(b);
        }
        session.sendBinary(bytes);
    }

    /**
     * 当接收到Netty的事件时，对该方法进行回调
     * @param session
     * @param evt
     */
    @OnEvent
    public void onEvent(Session session, Object evt) {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent idleStateEvent = (IdleStateEvent) evt;
            switch (idleStateEvent.state()) {
                case READER_IDLE:
                    System.out.println("read idle");
                    break;
                case WRITER_IDLE:
                    System.out.println("write idle");
                    break;
                case ALL_IDLE:
                    System.out.println("all idle");
                    break;
                default:
                    break;
            }
        }
    }

}
